#pragma once

#include "IDomain2.h"
#include "math.h"
#include "MinkowskiOperation2.h"


/** @todo share implementation with MinkowskiSum2  */
class MinkowskiDifference2 : public IConvexDomain2
{
public:
	//for collision detection
	class InternalPoint
	{
	public:
		InternalPoint();
		InternalPoint(const MinkowskiDifference2& difference);
		const Vector2 point() const	{	return point_;	}
		const Vector2 pointOn1() const	{	return pointOn1_;	}
		const Vector2 pointOn2() const	{	return pointOn2_;	}

	private:
		Vector2 pointOn1_;
		Vector2 pointOn2_;
		Vector2 point_;
	};

	class SupportPoint
	{
	public:
		SupportPoint();
		SupportPoint(const MinkowskiDifference2& difference, const Vector2& normal);
		const Vector2 normal() const	{	return point_;	}
		const Vector2 point() const	{	return point_;	}
		const Vector2 pointOn1() const	{	return pointOn1_;	}
		const Vector2 pointOn2() const	{	return pointOn2_;	}

	private:
		Vector2 normal_;
		Vector2 pointOn1_;
		Vector2 pointOn2_;
		Vector2 point_;
	};

public:
	MinkowskiDifference2();
	MinkowskiDifference2(const IConvexDomain2& p1, const Vector2& t1, const IConvexDomain2& p2, const Vector2& t2);
	void reset(const IConvexDomain2& domainA, const Vector2& positionA, const IConvexDomain2& domainB, const Vector2& positionB);

	const IConvexDomain2& domainA() const {	return *p1; }
	const Vector2&		  positionA() const	{	return *t1;	}
	const IConvexDomain2& domainB() const {	return *p2; }
	const Vector2&		  positionB() const	{	return *t2;	}
	const Vector2		  position() const;

	virtual const Vector2 internalPoint() const;
	void internalPointEx(InternalPoint& result) const;
	virtual const Vector2 supportPoint(const Vector2& normal) const;
	void supportPointEx(const Vector2& normal, SupportPoint& supportPoint) const;

private:
	friend class SupportPoint;

	const IConvexDomain2*	p1;
	const Vector2*			t1;
	const IConvexDomain2*	p2;
	const Vector2*			t2;
};